package com.itbaizhan.clouddemoorder.config;

import com.itbaizhan.Constant;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.jwt.crypto.sign.MacSigner;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;


@Configuration
@EnableResourceServer //开启资源服务器
public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {


    /**
     *  用户资源服务器向远程服务器发起认证请求, 对token进行认证
     * @param resources
     * @throws Exception
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        //设置资源服务器资源id
        ResourceServerSecurityConfigurer configurer = resources.resourceId(Constant.order_resource_id);
        configurer.tokenStore(tokenStore()).stateless(true);  //jwt改造token是无状态设置保存在客户端, session是有状态设置

    }

    /**
     * 此方法用于创建令牌存储对象
     * @return
     */
    private TokenStore tokenStore() {
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    /**
     *  返回令牌转换器
     * @return
     */
    private JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
        jwtAccessTokenConverter.setSigningKey(Constant.sign_key);  //签名密钥
        jwtAccessTokenConverter.setVerifier(new MacSigner(Constant.sign_key)); //验证时使用的密钥, 和签名使用的密钥一样
        return jwtAccessTokenConverter;
    }

    /**
     * 对不同特点的接口区别对待, 例如: 登录页面就不需要授权就可以访问, 其它资源接口需要授权认证才能访问
     * @param http
     * @throws Exception
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) //设置session的创建策略
            .and()
            .authorizeRequests()
            .antMatchers("/order/**").authenticated()  //以order开头的接口需要认证授权才能访问
            .anyRequest().permitAll();  //其他请求无需要认证
    }
}
